#Requires AutoHotkey v2.0
#Include SimLog.ahk

; 计算文件哈希值
; v1.0(bate)
; 目前仅仅支持SHA256算法
class FHashCode {

    __New(funEn := "SHA256", tempFile := A_ScriptDir . "\temp.Tmp") {

        ; 哈希算法
        this.funEn := funEn  

        ;临时文件路径
        this.tempFile := tempFile  
        
        ; 哈希值的长度(16进制)
        this.hashLen := 64 
        
        ; 是否在获取文件哈希值后删除临时文件(默认 false, 程序执行速度会快一点)
        this.delTempFileIs := false 

        ; 代码
    }
    

    ; 判断单个字符是否符合哈希值的规则(A-F,a-f,0-9)
    static _match(ch) {
        
        ; 判断是否是数字(0-9)
        if (IsDigit(ch)) {
            return true
        }
        
        ; 判断是否是字母(A-F,a-f)
        if InStr("abcdefABCDEF", ch) {
            return true
        }
        
        ; 都不是的话不符合哈希码规则
        return false
    }

    hashFile(filePath, funEn := this.funEn) {

        ; 使用 Format 函数构建命令字符串，{1}文件路径 {2}哈希算法 {3}临时文件路径
        cmd := Format('certutil -hashfile "{1}" {2} > "{3}"', filePath, this.funEn, this.tempFile)

        ; 直接使用 CMD 运行命令
        RunWait(A_ComSpec . ' /c ' . cmd, , 'Hide')

        ; 检查 temp.txt 是否成功生成
        if (!FileExist(this.tempFile)) {
            MsgBox "未能生成哈希值文件。"
            ExitApp
        }

        ; 读取 temp.txt
        strTemp := FileRead(this.tempFile)
        
        ; 用于循环的变量(理论这里可以去掉)
        match := false
        count := 0
        
        ; 提取哈希码
        loop parse strTemp {

            if (FHashCode._match(A_LoopField)) { ; 匹配[0-9][a-f][A-F]
                hash .= A_LoopField
                match := true
                count++
            } else if (A_LoopField == " ") { ; 匹配空格,但是视为无效字符
                match := true
            } else {
                match := false
            }

            ; 出现未匹配的字符()
            if (!match) {
                count := 0
                hash := ""
            }

            ; SHA256的长度为64
            if (count == this.hashLen) {
                break
            }

        }
        
        ; 删除目录
        if(this.delTempFileIs){
            FileDelete(this.tempFile)
        }

        return hash
    }
}


